// Fill out your copyright notice in the Description page of Project Settings.


// ReSharper disable All
#include "PackageTool/CommonPackTool.h"
#include "IPlatformFilePak.h"
#include "Framework/Notifications/NotificationManager.h"
#include "Misc/NamePermissionList.h"
#include "Internationalization/Internationalization.h"

UCommonPackTool::UCommonPackTool()
{
	PakPlatform = new FPakPlatformFile();
	PakPlatform->Initialize(&FPlatformFileManager::Get().GetPlatformFile(), TEXT(""));
	result = 0;
}

UCommonPackTool::~UCommonPackTool()
{
	
}

void UCommonPackTool::LoadAssetPackage(FString InpakFullPath)
{
	FPlatformFileManager::Get().SetPlatformFile(*PakPlatform);

	PakFileFullPath = InpakFullPath;

	FPakFile* TmpPak = new FPakFile(PakPlatform, *PakFileFullPath, false);
	
	FoundFilenames.Empty();
	result = TmpPak->AddRef();

	const FString PakMountPoint = TmpPak->GetMountPoint();
	const int32 PPos = PakMountPoint.Find("Content/");
	NewMountPoint = PakMountPoint.RightChop(PPos);
	NewMountPoint = FPaths::ProjectDir() + NewMountPoint; //FString NewMountPoint = "../../../DBJTest/Content/DLC/";
	
	TmpPak->SetMountPoint(*NewMountPoint);

	
	if (!PakPlatform->Mount(*PakFileFullPath, 1, *NewMountPoint))
	{
		UE_LOG(LogPakFile, Warning, TEXT("Mount Pak Failed = %s"), *NewMountPoint);
	}
	
	if (TmpPak)
	{
		TmpPak->FindPrunedFilesAtPath(FoundFilenames, *TmpPak->GetMountPoint(), true, false, false);
	}
	
	result = TmpPak->Release();
	
	TmpPak = nullptr;
}

void UCommonPackTool::LoadAsset(
	FString AssetNameWithoutPathAndSuffix, //资产名称
	bool bIsLevelAsset, //是否是资产，false为关卡
	TArray<FAssetPackageConfig>& AssetObjects, //bIsLevelAsset = false时有效
	TArray<FString>& LevelRefPaths //bIsLevelAsset = true时有效
	)
{
	if (FoundFilenames.Num() > 0)
	{
		if (!bIsLevelAsset)
		{
			//介于资产种类繁多，但大部分都是继承自UObject,遂具体类型要在蓝图侧强转为需要的类型
			for (FString& Filename : FoundFilenames)
			{
				FString NewFileName;

				Conv_RealPath_RefPath(Filename, NewFileName, bIsLevelAsset);
				
				const int32 Pos = NewFileName.Find("/", ESearchCase::IgnoreCase, ESearchDir::FromEnd);
				FString AssetName = NewFileName.RightChop(Pos + 1);

				AssetName = L"." + AssetName + L"_C";
				NewFileName += AssetName; // /game/xxxx/xxxx.xxxx_C
				
				UClass* LoadedClass = StaticLoadClass(UObject::StaticClass(), nullptr, *NewFileName);

				FAssetPackageConfig AssetConfig = {};

				AssetConfig.RefPath = NewFileName;
				AssetConfig.RefObject = NewObject<UObject>(this, LoadedClass);
				
				AssetObjects.Add(AssetConfig);
			}
			return;
		}

		for (FString& Filename : FoundFilenames)
		{
			// /Script/Engine.World'/Game/MAPS/ListTest.ListTest_C'
			FString NewFileName;

			Conv_RealPath_RefPath(Filename, NewFileName, bIsLevelAsset);
			
			const int32 Pos = NewFileName.Find("/", ESearchCase::IgnoreCase, ESearchDir::FromEnd);
			FString AssetName = NewFileName.RightChop(Pos + 1);

			AssetName = L"." + AssetName + L"_C";
			NewFileName += AssetName; // /game/xxxx/xxxx.xxxx_C
				
			//具体要加载哪个关卡在蓝图侧处理，这里仅提供相对路径
			LevelRefPaths.Add(NewFileName);
		}
	}
}

TArray<UObject*> UCommonPackTool::LoadAssetPackFromFBX(const FString& DestinationPath, bool bAllowAsyncImport)
{
	// if (!GetWritableFolderPermissionList()->PassesStartsWithFilter(DestinationPath))
	// {
	// 	NotifyBlockedByWritableFolderFilter();
	// 	return TArray<UObject*>();
	// }
	//
	 TArray<UObject*> ReturnObjects;
	// FString FileTypes, AllExtensions;
	// TArray<UFactory*> Factories;
	//
	// // Get the list of valid factories
	// for (TObjectIterator<UClass> It; It; ++It)
	// {
	// 	UClass* CurrentClass = (*It);
	//
	// 	if (CurrentClass->IsChildOf(UFactory::StaticClass()) && !(CurrentClass->HasAnyClassFlags(CLASS_Abstract)))
	// 	{
	// 		UFactory* Factory = Cast<UFactory>(CurrentClass->GetDefaultObject());
	// 		if (Factory->bEditorImport)
	// 		{
	// 			Factories.Add(Factory);
	// 		}
	// 	}
	// }
	//
	// TMultiMap<uint32, UFactory*> FilterIndexToFactory;
	//
	// // Generate the file types and extensions represented by the selected factories
	// ObjectTools::GenerateFactoryFileExtensions(Factories, FileTypes, AllExtensions, FilterIndexToFactory);
	//
	// if (UInterchangeManager::IsInterchangeImportEnabled())
	// {
	// 	TArray<FString> InterchangeFileExtensions = UInterchangeManager::GetInterchangeManager().GetSupportedFormats(EInterchangeTranslatorType::Assets);
	// 	ObjectTools::AppendFormatsFileExtensions(InterchangeFileExtensions, FileTypes, AllExtensions, FilterIndexToFactory);
	// }
	//
	// FileTypes = FString::Printf(TEXT("All Files (%s)|%s|%s"), *AllExtensions, *AllExtensions, *FileTypes);
	//
	// // Prompt the user for the filenames
	// TArray<FString> OpenFilenames;
	// IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
	// bool bOpened = false;
	// int32 FilterIndex = -1;
	//
	// if (DesktopPlatform)
	// {
	// 	const void* ParentWindowWindowHandle = FSlateApplication::Get().FindBestParentWindowHandleForDialogs(nullptr);
	//
	// 	bOpened = DesktopPlatform->OpenFileDialog(
	// 		ParentWindowWindowHandle,
	// 		LOCTEXT("ImportDialogTitle", "Import").ToString(),
	// 		FEditorDirectories::Get().GetLastDirectory(ELastDirectory::GENERIC_IMPORT),
	// 		TEXT(""),
	// 		FileTypes,
	// 		EFileDialogFlags::Multiple,
	// 		OpenFilenames,
	// 		FilterIndex
	// 	);
	// }
	//
	// if (bOpened)
	// {
	// 	if (OpenFilenames.Num() > 0)
	// 	{
	// 		UFactory* ChosenFactory = nullptr;
	// 		if (FilterIndex > 0)
	// 		{
	// 			ChosenFactory = *FilterIndexToFactory.Find(FilterIndex);
	// 		}
	//
	//
	// 		FEditorDirectories::Get().SetLastDirectory(ELastDirectory::GENERIC_IMPORT, OpenFilenames[0]);
	// 		const bool bSyncToBrowser = false;
	// 		TArray<TPair<FString, FString>>* FilesAndDestination = nullptr;
	// 		ReturnObjects = ImportAssets(OpenFilenames, DestinationPath, ChosenFactory, bSyncToBrowser, FilesAndDestination, bAllowAsyncImport);
	// 	}
	// }

	return ReturnObjects;
}

void UCommonPackTool::Conv_RealPath_RefPath(const FString& RealPath, FString& RefPath, bool bIsLevel)
{
	FString NewFileName = RealPath;
	!bIsLevel ? NewFileName.RemoveFromEnd(L"uasset") : NewFileName.RemoveFromEnd(L"umap");
	const int32 Pos = NewFileName.Find("/Content/");
	NewFileName = NewFileName.RightChop(Pos + 8);
	RefPath = "/Game" + NewFileName;
}

//TSharedRef<FPathPermissionList>& UCommonPackTool::GetWritableFolderPermissionList() const
//{
//	return const_cast<TSharedRef<FPathPermissionList>&>(WritableFolderPermissionList);
//}

void UCommonPackTool::NotifyBlockedByWritableFolderFilter() const
{
	//FSlateNotificationManager::Get().AddNotification(FNotificationInfo(LOCTEXT("NotifyBlockedByWritableFolderFilter", "Folder is locked")));
}
